package tcc.wa.persistence.dao;

import java.sql.Date;

import tcc.wa.model.CurrentWeatherCondition;
import tcc.wa.model.GeographicCoordinate;
import tcc.wa.model.Location;
import tcc.wa.persistence.dao.base.DAOBase;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;

/**
 * Data access object class responsible for CurrentWeatherCondition 
 * persistence management.
 */
public class CurrentWeatherConditionDAO extends DAOBase {

	private final String findLastCurrentWeatherConditionString = 
			"SELECT * FROM " + FORECAST_TABLE_NAME + " f INNER JOIN " + CURRENT_WEATHER_CONDITION_TABLE_NAME + 
				" cwc ON cwc.forecast_id = f.id INNER JOIN " + LOCATION_TABLE_NAME + " l ON f.location_id = l.id";
	
	private final String findCurrentWeatherConditionForecastidString = "SELECT forecast_id FROM currentweathercondition LIMIT 1";
	
	public CurrentWeatherConditionDAO(Context context) {
		super(context);
	}
	
	/**
	 * Saves the current weather condition on the database.
	 *
	 * @param currentWeatherCondition the current weather condition to be saved
	 */
	public void save(CurrentWeatherCondition currentWeatherCondition) {
		long oldForecastId = findForecastId();
		SQLiteDatabase database = getWritableDatabase();
		if (oldForecastId != 0) {
			database.delete(CURRENT_WEATHER_CONDITION_TABLE_NAME, null, null);
			database.delete(FORECAST_TABLE_NAME, "id=?", new String[] { String.valueOf(oldForecastId) });
		}
		ContentValues forecastValues = new ContentValues();
		forecastValues.put("location_id", currentWeatherCondition.getLocation().getId());
		forecastValues.put("date", currentWeatherCondition.getDate().getTime());
		long forecastId = database.insert(FORECAST_TABLE_NAME, null, forecastValues);
		ContentValues currentWeatherConditionValues = new ContentValues();
		currentWeatherConditionValues.put("forecast_id", forecastId);
		currentWeatherConditionValues.put("current_temperature", currentWeatherCondition.getCurrentTemperature());
		currentWeatherConditionValues.put("relative_humidity", currentWeatherCondition.getCurrentRelativeHumidity());
		currentWeatherConditionValues.put("precipitation", currentWeatherCondition.getCurrentPrecipitation());
		currentWeatherConditionValues.put("maximum_temperature", currentWeatherCondition.getMaximumTemperature());
		currentWeatherConditionValues.put("minimum_temperature", currentWeatherCondition.getMinimumTemperature());
		long currentWeatherConditionId = database.insert(CURRENT_WEATHER_CONDITION_TABLE_NAME, null, currentWeatherConditionValues);
		currentWeatherCondition.setForecastId(forecastId);
		currentWeatherCondition.setCurrentWeatherConditionId(currentWeatherConditionId);
		close();
	}
	
	/**
	 * Finds the last current weather condition.
	 *
	 * @return the last current weather condition
	 */
	public CurrentWeatherCondition findLast() {
		CurrentWeatherCondition currentWeatherCondition = null;
		SQLiteDatabase database = getWritableDatabase();
		Cursor cursor = database.rawQuery(findLastCurrentWeatherConditionString, null);
		if (cursor.moveToFirst()) {
			currentWeatherCondition = new CurrentWeatherCondition();
			currentWeatherCondition.setForecastId(cursor.getLong(0));
			currentWeatherCondition.setDate(new Date(cursor.getLong(1)));
			currentWeatherCondition.setCurrentWeatherConditionId(cursor.getLong(3));
			currentWeatherCondition.setMaximumTemperature(cursor.getDouble(5));
			currentWeatherCondition.setMinimumTemperature(cursor.getDouble(6));
			currentWeatherCondition.setCurrentTemperature(cursor.getDouble(7));
			currentWeatherCondition.setCurrentRelativeHumidity(cursor.getDouble(8));
			currentWeatherCondition.setCurrentPrecipitation(cursor.getDouble(9));
			Location location = new Location();
			location.setId(cursor.getLong(10));
			location.setCity(cursor.getString(11));
			location.setState(cursor.getString(12));
			location.setRegion(cursor.getString(13));
			location.setCountry(cursor.getString(14));
			location.setGeographicCoordinate(new GeographicCoordinate(cursor.getDouble(15), cursor.getDouble(16)));
			currentWeatherCondition.setLocation(location);
		}
		close();
		return currentWeatherCondition;
	}
	
	/**
	 * Finds the forecast id.
	 *
	 * @return the forecast id
	 */
	private long findForecastId() {
		long forecastId = 0;
		SQLiteDatabase database = getWritableDatabase();
		Cursor cursor = database.rawQuery(findCurrentWeatherConditionForecastidString, null);
		if (cursor.moveToFirst()) {
			forecastId = cursor.getLong(0);
		}
		close();
		return forecastId;
	}
}